# barco/sandbox.py

from . import sandboxconfig
from . import sandboxmoduletree
from . import srcrepos
from . import binrepos

import os

class Sandbox(object):
    
    def __init__(self):
        self.config = sandboxconfig.SandboxConfig()
        self.srcrepos = srcrepos.Client()
        self.binrepos = binrepos.Client()
        return None

    def set_config(self, config):
        self.config.set(config)
        return None

    def create(self, *args):
        
        # process the configuration file
        info = self.config.process()

        # create starting workspaces
        src_workspace = self.srcrepos.create_workspace(info.get_src_directory(), info.get_src_branch())
        bin_workspace = self.binrepos.create_workspace(info.get_bin_directory(), info.get_bin_branch())

        # create the moduletree
        module_tree = sandboxmoduletree.SandboxModuleTree(src_workspace, bin_workspace)
 
        # checkout new modules
        for module in info.get_modules(): 
            m = module_tree.create_module(module)
            m.set_source()
            m.checkout(module_tree)

        # create scripts and makefiles
        self.create_configure_script(info.get_src_directory(), info.get_bin_directory(), module_tree)
        self.create_makefile(info.get_src_directory())

        return 0

    def update(self, *args):

        # Process the configuration file
        info = self.config.process()
       
        # update "existing" workspaces
        src_workspace = self.srcrepos.update_workspace(info.get_src_directory(), info.get_src_branch())
        bin_workspace = self.binrepos.update_workspace(info.get_bin_directory(), info.get_bin_branch())

        # create the moduletree
        module_tree = sandboxmoduletree.SandboxModuleTree(src_workspace, bin_workspace)
        
        # checkout/update new and existing modules
        for module in info.get_modules(): 
            m = module_tree.create_module(module)
            m.set_source()
            m.update(module_tree)

        # create/update scripts and makefiles
        self.create_configure_script(info.get_src_directory(), info.get_bin_directory(), module_tree)
        self.create_makefile(info.get_src_directory())

        return 0

    def create_configure_script(self, src_dir, bin_dir, tree):
        if not os.path.isabs(src_dir): src_dir =  os.path.join(os.getcwd(), src_dir)
        if not os.path.isabs(bin_dir): bin_dir =  os.path.join(os.getcwd(), bin_dir)     
        f = open(os.path.join(src_dir, 'configure'), 'w')
        os.fchmod(f.fileno(), 0755)
        f.write('#!/usr/bin/env python\n')
        f.write('import os\n')
        f.write('src_dir = \'%s\'\n' % src_dir)
        f.write('bin_dir = \'%s\'\n' % bin_dir)       
        f.write('sconscript = open(\'SConstruct\', \'w\')\n')
        f.write('sconscript.write(\'global_env = Environment()\\n\')\n')      
        f.write('sconscript.write(\'global_env[\\\'PREFIX\\\'] = global_env.Dir(\\\'#/%s\\\')\\n\' % os.path.relpath(bin_dir, os.getcwd()))\n')
        f.write('sconscript.write(\'global_env.Default(global_env.Dir(\\\'$PREFIX\\\'))\\n\')\n')
        for m in tree.get_src_stack():
            g =  m.get_description().get_exported_globals()
            for k in g.keys():  f.write('sconscript.write(\'global_env[\\\'%s\\\'] = \\\'%s\\\' # from %s\\n\')\n' % (k, g[k], m.get_name()))
        
        for m in tree.get_bin_stack():    
            pass
        
        f.write('sconscript.write(\'global_env[\\\'SRCREPOS_FLAGS\\\'] = dict()\\n\')\n')  
        
        for m in tree.get_src_stack():
            flags =  m.get_description().get_exported_flags()
            f.write('sconscript.write(\'global_env[\\\'SRCREPOS_FLAGS\\\'][\\\'%s\\\'] = dict()\\n\')\n' % m.get_name())
            for k in flags.keys(): f.write('sconscript.write(\'global_env[\\\'SRCREPOS_FLAGS\\\'][\\\'%s\\\'][\\\'%s\\\'] = \\\'%s\\\'\\n\')\n' % (m.get_name(), k, flags[k]))

        for m in tree.get_bin_stack():    
            pass
                   
        for m in tree.get_src_stack():
            f.write('sconscript.write(\'global_env.VariantDir(global_env.Dir(\\\'#/%s\\\'), global_env.Dir(\\\'#/%%s/%s\\\'))\\n\' %% os.path.relpath(src_dir, os.getcwd()))\n' % (m.get_name(), m.get_name()))  
            f.write('sconscript.write(\'global_env[\\\'MODULE\\\'] = \\\'%s\\\'\\n\')\n' % m.get_name())
            f.write('sconscript.write(\'global_env.SConscript(global_env.File(\\\'#/%s/sconscript.py\\\'), exports=\\\'global_env\\\')\\n\')\n' % m.get_name())

        f.write('sconscript.write(\'global_env.CreateUploadPackage()\\n\')\n')
        f.write('sconscript.close()\n')
        f.close()
        return None

    def create_makefile(self, directory):
        if (os.path.isabs(directory)): d = directory
        else: d = os.path.join(os.getcwd(), directory)
        configure = os.path.join(d, 'configure')
        f = open('Makefile', 'w')
        f.write('.PHONY: release debug all\n')
        f.write('release:\n')
        f.write('\t@mkdir -p build_release\n')  
        build_dir = os.path.join(os.getcwd(), 'build_release')
        f.write('\t@cd build_release && %s\n' % os.path.relpath(configure, build_dir))
        f.write('\t@scons -C build_release\n')
        f.write('debug:\n')
        f.write('\t@mkdir -p build_debug\n')
        build_dir = os.path.join(os.getcwd(), 'build_debug')
        f.write('\t@cd build_debug && %s\n' % os.path.relpath(configure, build_dir))
        f.write('\t@scons -C build_debug\n')
        f.write('all: release debug\n')
        f.close()
        return None

